package com.xiaoge.system.controller;


import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaoge.auth.annotation.ControllerEndpoint;
import com.xiaoge.auth.security.UserInfo;
import com.xiaoge.response.Result;
import com.xiaoge.response.ResultCode;
import com.xiaoge.system.entity.Role;
import com.xiaoge.system.entity.User;
import com.xiaoge.system.service.RoleService;
import com.xiaoge.system.service.UserService;
import com.xiaoge.system.vo.RoleTransferItemVO;
import com.xiaoge.system.vo.UserVo;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;


import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author xiaoge
 * @since 2021-02-02
 */
@RestController
@RequestMapping("/user")
//允许跨域
@CrossOrigin
public class UserController {

    @Resource
    private UserService userService;

    @Autowired
    private RoleService roleService;

    private PasswordEncoder passwordEncoder;

    public UserController(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    /**
     * 分页查询用户
     *
     * @param current
     * @param size
     * @param userVo
     * @return
     */
    @ApiOperation(value = "分页查询用户")
    @PostMapping("/findUserPage")
    public Result findUserPage(@RequestParam(defaultValue = "1") Integer current,
                               @RequestParam(defaultValue = "6") Integer size,
                               @RequestBody UserVo userVo) {
        //取得分页条件
        Page<User> page = new Page<>(current, size);
        //获得wragger
        QueryWrapper<User> queryWrapper = getWrapper(userVo);

        //执行查询
        IPage<User> userPage = userService.findUserPage(page, queryWrapper,userVo.getRoleId());

        long total = userPage.getTotal();
        List<User> records = userPage.getRecords();
        return Result.ok().data("total", total).data("records", records);
    }

    /**
     * 用户角色信息
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "已有角色", notes = "根据用户id，获取用户已经拥有的角色")
    @GetMapping("/haveRoles")
    public Result roles(Long id) {
        List<Role> values = userService.getRoles(id);
        List<Long> values1 = new ArrayList<>();
        for (Role value : values) {
            values1.add(value.getId());
        }
        List<Role> list = roleService.list();
        //转成前端需要的角色Item
        List<RoleTransferItemVO> itemVOList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (Role role : list) {
                RoleTransferItemVO item = new RoleTransferItemVO();
                item.setLabel(role.getRoleName());
                item.setDisabled(role.getStatus() == 0);
                item.setKey(role.getId());
                itemVOList.add(item);
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("roles", itemVOList);
        map.put("values", values1);
        return Result.ok().data(map);
    }

    /**
     * 分配角色
     *
     * @param id
     * @param rids
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "分配角色失败", operation = "分配角色")
    @ApiOperation(value = "分配角色", notes = "角色分配给用户")
    @PostMapping("/assignRoles")
    public Result assignRoles(Long id, @RequestBody Long[] rids) {
        userService.assignRoles(id, rids);
        return Result.ok();
    }

    /**
     * 添加用户
     *
     * @param user
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "添加用户失败", operation = "添加用户")
    @ApiOperation(value = "添加用户")
    @PostMapping("/addUser")
    public Result addUser(@RequestBody User user) {
        return userService.addUser(user);
    }

    /**
     * 修改用户信息
     *
     * @param user
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "修改用户失败", operation = "修改用户信息")
    @ApiOperation(value = "修改用户信息")
    @PostMapping("/updateUser")
    public Result updateUser(@RequestBody User user) {
        User updateUser = new User();
        updateUser.setEmail(user.getEmail());
        updateUser.setType(user.getType());
        updateUser.setSex(user.getSex());
        updateUser.setStatus(user.getStatus());
        updateUser.setDepartmentId(user.getDepartmentId());
        updateUser.setAvatar(user.getAvatar());
        updateUser.setNickname(user.getNickname());
        updateUser.setPhoneNumber(user.getPhoneNumber());
        updateUser.setBirth(user.getBirth());
        try {
            UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
            userUpdateWrapper.eq("username", user.getUsername());
            userService.update(updateUser, userUpdateWrapper);
            return Result.ok();
        } catch (Exception e) {
            return Result.error();
        }
    }


    /**
     * 修改用户密码
     *
     * @param oldPassword
     * @param newPassword
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "修改密码失败", operation = "修改用户密码")
    @ApiOperation(value = "修改用户密码")
    @PostMapping("/updateUserPassWord")
    public Result updateUserPassWord(String oldPassword, String newPassword) {
        User updateUser = new User();
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserInfo userInfo = (UserInfo) authentication.getPrincipal();
        if (passwordEncoder.matches(oldPassword, userInfo.getPassword())) {
            updateUser.setPassword(passwordEncoder.encode(newPassword));
        } else {
            return Result.error(ResultCode.USER_CREDENTIALS_ERROR);
        }
        try {
            UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
            userUpdateWrapper.eq("username", userInfo.getUsername());
            userService.update(updateUser, userUpdateWrapper);
            return Result.error(ResultCode.USER_CREDENTIALS_EXPIRED);
        } catch (Exception e) {
            return Result.error();
        }
    }

    /**
     * 更新用户状态
     *
     * @param id
     * @param status
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "用户更新状态失败", operation = "用户|禁用/启用")
    @ApiOperation(value = "更新状态", notes = "禁用和更新两种状态")
    @PutMapping("/updateStatus")
    public Result updateStatus(Long id, Integer status) {
        User user = new User();
        user.setId(id);
        user.setStatus(status);
        userService.updateById(user);
        return Result.ok();
    }

    /**
     * 删除单个用户
     *
     * @param id
     * @return Result
     */
    @ControllerEndpoint(exceptionMessage = "删除用户失败", operation = "删除用户")
    @ApiOperation(value = "删除用户")
    @PostMapping("/deleteUserById")
    public Result deleteUserById(Long id) {
       return userService.delUser(id);
    }

    /**
     * 批量删除用户
     *
     * @param ids
     * @return Result
     */
    @ApiOperation(value = "批量删除")
    @PostMapping("/deleteUsersByIds")
    public Result deleteUsersByIds(String ids) {
        String[] idList = ids.split(",");
        userService.removeByIds(Arrays.asList(idList));
        return Result.ok().message("批量删除成功");
    }

    /**
     * 导出所有用户的excel表格
     *
     * @param response
     * @throws IOException
     */
    @ControllerEndpoint(exceptionMessage = "导出角色excel失败", operation = "导出角色excel")
    @ApiOperation(value = "导出excel", notes = "导出所有用户的excel表格")
    @PostMapping("/excel")
    public void export(HttpServletResponse response) throws IOException {
        List<User> users = userService.findAll();
        ExportParams params = new ExportParams("用户表", "用户表", ExcelType.HSSF);
        Workbook workbook = ExcelExportUtil.exportExcel(params, User.class, users);
        ServletOutputStream outputStream = null;
        try {
            response.setHeader("content-type", "application/octet-stream");
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("用户表.xls", "UTF-8"));
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private QueryWrapper<User> getWrapper(UserVo userVo) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (userVo != null) {

            //查询每个条件
            if (!ObjectUtils.isEmpty(userVo.getDepartmentId())) {
                queryWrapper.eq("department_id", userVo.getDepartmentId());
            }
            if (!ObjectUtils.isEmpty(userVo.getSex())) {
                queryWrapper.eq("sex", userVo.getSex());
            }

            //模糊查询
            if (!ObjectUtils.isEmpty(userVo.getUsername())) {
                queryWrapper.like("username", userVo.getUsername());
            }
            if (!ObjectUtils.isEmpty(userVo.getEmail())) {
                queryWrapper.like("email", userVo.getEmail());
            }
            if (!ObjectUtils.isEmpty(userVo.getNickname())) {
                queryWrapper.like("nickname", userVo.getNickname());
            }
        }
        return queryWrapper;
    }
}
